#include <stdexcept>
#include "../ged/typedefs.hpp"
#include "Image.hpp"
#include "../gil/flattened_view.hpp"

namespace ged {

Image::Image(const GILPoint& sz)
	: selected_idx_(0)
{
	if (sz < GILPoint(0, 0))
		throw std::out_of_range("ged::Image::Image");
	initView(sz);
}

void Image::addLayer(PGILImage image)
{
	PImageLayer layer(new ImageLayer(image));
	layers_.push_back(layer);
	selected_idx_ = layers_.size() - 1;
}

const PImageLayer Image::getLayer() const
{
	return layers_.at(selected_idx_);
}

void Image::selectLayer(std::size_t i)
{
	if (i >= layers_.size()) {
		throw std::out_of_range("Image::selectLayer");
	}
	selected_idx_ = i;
}

int Image::getActiveLayer() const
{
	return selected_idx_;
}

void Image::deleteLayer()
{
	if (layers_.empty())
		return;

	layers_.pop_back();
	selected_idx_ = layers_.empty() ? 0 : layers_.size() - 1;
}

void Image::initView(const GILPoint& sz)
{
	view_ = view_type(sz, locator_type(GILPoint(0, 0), GILPoint(1, 1), deref_type(&(this->layers_))));
}

const Image::view_type Image::getView()
{
	// Zmiana wymiarów płótna jeżeli zmieniły się wymiary warstwy
	// tła (pierwsza na stosie)
	GILPoint dims = layers_[0]->getView().dimensions();
	if (layers_.size() && view_.dimensions() != dims) {
		initView(dims);
	}

	return view_;
}

} // namespace ged
